/*
 * Copyright (C) 2013 Daniel Wasilew <daniel.wasilew@codeminer.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.codeminer.parts.database.dao;

import org.codeminer.database.DatabaseConnection;
import org.codeminer.database.DatabaseException;
import org.codeminer.parts.database.sql.From;
import org.codeminer.parts.database.sql.SQL;
import org.codeminer.parts.library.Album;
import org.codeminer.parts.library.Artist;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Daniel Wasilew <daniel.wasilew@codeminer.org>
 */
public final class ArtistDAO extends DAO {

    private ArtistDAO() {
    }

    public static long store(Artist artist, DatabaseConnection connection) throws DatabaseException {
        connection.accuireWriteLock();
        try {
            updateAndGetNextId(connection, artist);
            String insertStatement = SQL.insertInto("Artists").values().value(artist.getOid()).value(artist.getName()).toSQL();
            executeInsert(connection, insertStatement);
            return artist.getOid();
        } finally {
            connection.releaseWriteLock();
        }
    }

    public static boolean delete(Artist artist, DatabaseConnection connection) throws DatabaseException {
        validateIdentifiable(artist);
        String deleteStatement = SQL.delete().from("Artists").where("Artist_Id").is(artist.getOid()).toSQL();
        connection.accuireWriteLock();
        try {
            return executeUpdate(connection, deleteStatement);
        } finally {
            connection.releaseWriteLock();
        }
    }

    public static boolean update(Artist artist, DatabaseConnection connection) throws DatabaseException {
        validateIdentifiable(artist);
        String update = SQL.update("Artists").set("Artist_Name", artist.getName()).where("Artist_Id").is(artist.getOid()).toSQL();
        connection.accuireWriteLock();
        try {
            return executeUpdate(connection, update);
        } finally {
            connection.releaseWriteLock();
        }
    }

    public static Artist get(Artist searchCriteria, DatabaseConnection connection) throws DatabaseException {
        connection.accuireReadLock();
        ResultSet resultSet = null;
        try {
            String query;
            From from = SQL.select().from("Artists");
            if (searchCriteria.getOid() == -1) { //search by name
                query = from.where("Artist_Name").is(searchCriteria.getName()).toSQL();
            } else { //search by id
                query = from.where("Artist_Id").is(searchCriteria.getOid()).toSQL();
            }
            resultSet = connection.createStatement().executeQuery(query);
            if (resultSet.next()) {
                long oid = resultSet.getLong(1);
                String name = resultSet.getString(2);
                Artist result = new Artist(name);
                result.setOid(oid);
                return result;
            } else {
                return null;
            }

        } catch (SQLException ex) {
            throw new DatabaseException(ex);
        } finally {
            connection.releaseReadLock();
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException ignored) {
                }
            }
        }
    }

    public static List<Artist> findArtistForAlbum(Album album, DatabaseConnection connection) throws DatabaseException {
        validateIdentifiable(album);

        connection.accuireReadLock();
        try {
            String artistIdQuery = SQL.select("Artist_Id").from("ALBUMS_FOR_ARTISTS").where("Album_Id").is(album.getOid()).toSQL();
            List<Long> artistIds = queryIds(artistIdQuery, "Artist_Id", connection);
            List<Artist> result = new LinkedList<>();
            for (Long artistId : artistIds) {
                result.add(get(Artist.getOIdCriteria(artistId), connection));
            }

            return result;
        } finally {
            connection.releaseReadLock();
        }
    }
}
